package gui.Main;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import hypeerweb.HyPeerWeb;
import hypeerweb.HyPeerWebProxy;
import hypeerweb.Node;
import hypeerweb.WebId;
import communicator.ObjectDB;
import gui.newWindows.SetUpWindow;


import gui.Main.HyPeerWebDebugger;
import gui.newWindows.SetUpWindow;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.*;

import communicator.*;
/**
 * The central GUI used to display information about the HyPeerWeb and debug information
 * 
 * @author Matthew Smith
 *
 */
public class GUI extends JFrame
{
    private static GUI singleton = null;
    
    /** Main Debugger Panel**/
    private HyPeerWebDebugger debugger;
    
    private HyPeerWeb hypeerweb;
    private JScrollPane scrollPane;
    private static GUIhelper daemon;
    
    private static String targetIpAdress;
    private static int portNumber;
    
    public GUIhelper getHelper()
    {
        return daemon;
    }
    public static String getTargetIpAdress()
    {
        return targetIpAdress;
    }
    public static void setTargetIpAdress(String targetIpAdress)
    {
        GUI.targetIpAdress = targetIpAdress;
    }
    /**
     * Creates and initializes the GUI as being the root
     */
    public GUI(HyPeerWeb hypeerweb){

        //hypeerweb.clear();
        this.hypeerweb = hypeerweb;
        this.setTitle("HyPeerWeb DEBUGGER V 1.1");
        this.addWindowListener(new WindowAdapter() {
            
              public void windowClosing(WindowEvent we) {
                shutdown();
                System.exit(0);
              }
            });

        debugger = new HyPeerWebDebugger(this);
        scrollPane = new JScrollPane(debugger);
        scrollPane.setPreferredSize(new Dimension(debugger.WIDTH+20, debugger.HEIGHT));
        this.getContentPane().add(scrollPane);
        this.pack();
    }
    public GUI(HyPeerWeb hypeerweb,int pn,String ip){
       
        //hypeerweb.clear();
        this.hypeerweb = hypeerweb;
        this.setTitle("HyPeerWeb DEBUGGER V 1.1");
        this.addWindowListener(new WindowAdapter() {
            
              public void windowClosing(WindowEvent we) {
                shutdown();
                System.exit(0);
              }
            });
        debugger = new HyPeerWebDebugger(this);
        scrollPane = new JScrollPane(debugger);
        scrollPane.setPreferredSize(new Dimension(debugger.WIDTH+20, debugger.HEIGHT));
        this.getContentPane().add(scrollPane);
        this.pack();
        targetIpAdress=ip;
        portNumber=pn;
    }
    
    public GUI()
    {
        this.setTitle("HyPeerWeb DEBUGGER V 1.1");      
        this.addWindowListener(new WindowAdapter() {
            
              public void windowClosing(WindowEvent we) {
                shutdown();
                System.exit(0);
              }
            });
     
        this.pack();
    }
    private void shutdown(){
        hypeerweb.remove_helper(daemon.get_globalId());
        hypeerweb.close();
    }    
    
    public static GUI getSingleton(){
        if(singleton == null){
            try{
                singleton = new GUI();
                singleton.setVisible(true);
            }
            catch(Exception e)  {
                JOptionPane.showMessageDialog(null, e.getMessage(), "ERROR",JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
                System.exit(1);
            }
        }
        return singleton;
    }
    public static GUI getSingleton(HyPeerWeb hypeerweb){
        if(singleton == null){
            try{
                singleton = new GUI(hypeerweb);
                singleton.setVisible(true);

            }
            catch(Exception e)  {

                JOptionPane.showMessageDialog(null, e.getMessage(), "ERROR",JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
                hypeerweb.close();
                System.exit(1);
            }
        }
        return singleton;
    }
    
    /**
     * Start Point of the Program
     */
    private static ObjectDB db;

    public static void main (String[] args)
    {      
        singleton = new GUI();
        SetUpWindow setUpWindow = null;
        setUpWindow = new SetUpWindow(singleton, "Set Up");
        while(portNumber==0)
        {//waits for input from the window josh set up
            System.out.print("");
        }
        
        int pn=portNumber;
        String ip=targetIpAdress;
        String machineName = "mace";//this gets changed later
        try
        {
            machineName = InetAddress.getLocalHost().toString();
            machineName = machineName.split("/")[0];//grabs just our machine name to pass it over
        }
        catch (UnknownHostException e1)
        {
            e1.printStackTrace();
        }//the name of the computer that you are on
        
        PortNumber port = new PortNumber(40005);
        PortNumber.setApplicationsPortNumber(port);
        PeerCommunicator.createPeerCommunicator(port);
        MachineAddress.setMachineAddress(machineName);
        
        GUIhelper helper = new GUIhelper();
        GlobalObjectId glow = new GlobalObjectId();
        GlobalObjectId helperId = new GlobalObjectId();
        db = ObjectDB.getSingleton();
        daemon = helper;

        db.store(glow.getLocalObjectId(),singleton);
        db.store(helperId.getLocalObjectId(), helper);
        helper.set_helper_globalId(helperId);
  
        System.out.println("IP address: "+ glow.getMachineAddr() + "\nPort number: " 
                            + glow.getPortNumber() + "\nLocal ID: " + glow.getLocalObjectId() + "\n\n");
 
            helper.set_port(portNumber + "");
            helper.set_local_id(targetIpAdress);
            
            PortNumber port2 = new PortNumber(portNumber);
            LocalObjectId local2 = new LocalObjectId(Integer.MIN_VALUE);//the min local object id, i.e. the hypeerweb
            
            GlobalObjectId glow2 = new GlobalObjectId(targetIpAdress,port2,local2);
            HyPeerWebProxy proxy = new HyPeerWebProxy(glow2);
            GUIthread thread = new GUIthread();
            thread.start();  
            proxy.set_helper(helperId);
            //stop making a hypeerweb proxy
    
        try{
            singleton = new GUI(proxy,pn,ip);
            singleton.setVisible(true);
        }
        catch(Exception e)  {
             proxy.close();
             System.exit(1);
        }
        daemon.set_GUI(GUI.getSingleton(proxy));          
    }
    public static int getPortNumber()
    {
        return portNumber;
    }
    public static void setPortNumber(int portNumber)
    {
        GUI.portNumber = portNumber;
    }
    public static void executeCommand(String command){
        try {
            System.out.println("COMMAND: " + command);
            Runtime.getRuntime().exec(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Retrieves the HyPeerWeb Debugging Panel
     * @return HyPeerWebDebugger
     */
    public HyPeerWebDebugger getHyPeerWebDebugger() {
        return debugger;
    }
    
    public HyPeerWeb getHyPeerWeb(){
        return hypeerweb;
    }
    
    public void printToTracePanel(Object msg){
        debugger.getTracePanel().print(msg);
    }
    
    public void finalize(){
        hypeerweb.close();
    }

}
